package com.jxud.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jxud.Pojo.*;
import com.jxud.Pojo.PageOrder;
import com.jxud.enums.UserStatus;
import com.jxud.mapper.OrderMapper;
import com.jxud.mapper.OrderSqlProvider;
import com.jxud.mapper.UserMapper;
import com.jxud.service.OrderService;
import com.jxud.utils.HttpUtil;
import com.jxud.utils.JwtUtils;
import com.jxud.utils.OrderNumberGenerator;
import io.jsonwebtoken.Claims;
//import io.micrometer.common.util.StringUtils;
import org.apache.commons.lang3.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional
public class OrderServiceImpi implements OrderService {

    /**
     * 根据token获取userId
     *
     * @param req
     * @return
     */
    private Map<String, Object> getTokenData(HttpServletRequest req) {
        String token = req.getHeader("token");
        Claims claims = JwtUtils.parseJwt(token);
        Integer userId = (Integer) claims.get("id");
        String wxName = (String) claims.get("wxName");
        Map<String, Object> map = new HashMap<>();
        map.put("id", userId);
        map.put("wxName", wxName);
        return map;
    }

    private final ObjectMapper jsonMapper;

    private final HttpUtil httpUtil;

    // 构造函数注入（@RequiredArgsConstructor 自动生成）
    public OrderServiceImpi(ObjectMapper jsonMapper, HttpUtil httpUtil) {
        this.jsonMapper = jsonMapper;
        this.httpUtil = httpUtil;
    }

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserMapper userMapper;

    /**
     * 根据token 获取到当前客户的订单ServiceImpi
     *
     * @param request
     * @return
     */
    @Override
    public Map<String, Object> getOrdersByCustomerId(HttpServletRequest request, PageOrder pageOrder) {

        // 1. 日志记录分页参数
        log.info("订单查询参数 - page: {}, size: {}, offset: {}, courierNumber:{}",
                pageOrder.getPage(), pageOrder.getSize(), pageOrder.getOffset(), pageOrder.getCourierNumber());
//        获取到token中的id 和 WXName
        Map<String, Object> tokenData = getTokenData(request);
        Integer id = (Integer) tokenData.get("id");
        String wxName = (String) tokenData.get("wxName");
//        分页参数
        pageOrder.setOffset((pageOrder.getPage() - 1) * pageOrder.getSize());

//        查询符合条件的主订单
        List<Order> getOrderById = orderMapper.getOrderById(id, pageOrder, wxName);
        log.info("查询到的主订单:{}", getOrderById);
        int totalOrders = getOrderById.isEmpty() ? 0 : orderMapper.totalOrders(id, pageOrder, wxName);
        log.info("查询到的订单的总条数:{}", totalOrders);

//        在order表获取到符合条件的订单
        List<String> orderIds = getOrderById.stream()
                .map(Order::getOrderId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        if (orderIds.isEmpty()) {
            log.warn("用户 {} 的订单中未找到有效的 orderId", wxName);
            Map<String, Object> ordersMap = new HashMap<>();
            ordersMap.put("ordersList", Collections.emptyList());
            ordersMap.put("page", pageOrder.getPage());
            ordersMap.put("size", pageOrder.getSize());
            ordersMap.put("total", totalOrders);
            return ordersMap;
        }

//        查询订单的详细信息
        List<OrderItems> details = Collections.emptyList();
        try {
            details = orderMapper.getOrderItemByOrderId(orderIds);
            log.info("查询到 {} 条订单明细", details.size());
        } catch (Exception e) {
            log.error("查询订单明细失败，订单IDs: {}", orderIds, e);
            details = Collections.emptyList(); // 失败时返回空列表，避免中断
        }

//        按 orderId 分组商品明细
        Map<String, List<OrderItems>> detailMap = details.stream()
                .collect(Collectors.groupingBy(OrderItems::getOrderId));

//       绑定明细到主订单
        for (Order header : getOrderById) {
            header.setTbSoDetails(
                    detailMap.getOrDefault(header.getOrderId(), Collections.emptyList())
            );
        }
        Map<String, Object> ordersMap = new HashMap<>();
        ordersMap.put("ordersList", getOrderById);
        ordersMap.put("page", pageOrder.getPage());
        ordersMap.put("size", pageOrder.getSize());
        ordersMap.put("total", totalOrders);

        return ordersMap;
    }

    /**
     * 根据订单号获取订单的发货信息ServiceImpi
     *
     * @param orderId
     */
    @Override
    public void getOrderItemByOrderId(String orderId) {
        return;
    }


    /**
     * 创建单个订单 ServiceImpi
     *
     * @param order
     */
    @Override
    public String createOrder(Order order, HttpServletRequest request) {

        if (order == null) {
            log.warn("创建订单数据为空");
            return "创建订单数据为空";
        }

        //判断抖音平台是否提供订单号
        if ("抖音".equals(order.getPlatform())) {
            if (StringUtils.isBlank(order.getOrderId())) {
                log.warn("抖音平台必须输入订单号 否则无法下单");
                return "抖音平台必须输入订单号 否则无法下单";
            }
        }

        Map<String, Object> tokenData = getTokenData(request);
        log.info("tokenData:{}", tokenData);
        Integer id = (Integer) tokenData.get("id");
        String wxName = tokenData.get("wxName").toString();
        order.setUsername(String.valueOf(id));
        order.setCreatedAt(LocalDateTime.now());
        order.setUpdatedAt(LocalDateTime.now());
        order.setRoomname(wxName);

        log.info("---------------======order:{}", order);

        //生成订单号
        if (StringUtils.isEmpty(order.getOrderId())) {
            order.setOrderId(OrderNumberGenerator.generateOrderNumber());
        }
        order.setOrderStatus(0);
        log.info("订单信息是{}", order);
        orderMapper.insertOrder(order);   //创建主订单

        //创建订单商品明细
        for (OrderItems items : order.getTbSoDetails()) {
            items.setOrderId(order.getOrderId());
            log.info("创建订单{}", items);
            orderMapper.insertOrderItems(items);
            System.out.println("");
            log.info("累加的商品是{}", items);
            orderMapper.queryProducts(items.getProductCode());
        }
        return "订单创建成功";
    }

    /**
     * 查询单个订单不脱敏
     *
     * @param orderId 订单编号
     * @return
     */
    @Override
    public List<Order> getOrdersByIdDesens(String orderId) {
        return orderMapper.getOrdersByIdDesens(orderId);
    }

    /**
     * 更改订单的状态管理员
     *
     * @param updateOrderStatus
     * @param request
     */
    @Override
    public Result UpdateOrderStatus(UpdateOrderStatus updateOrderStatus, HttpServletRequest request) {

        Map<String, Object> tokenData = getTokenData(request);
        String wxName = (String) tokenData.get("wxName");

        if (!"admin".equals(wxName)) {
            log.warn("用户[{}]尝试修改订单状态，无权限", wxName);
            return Result.error("您没有操作权限");
        }
        // 更改成那个状态
        String targetStatus = updateOrderStatus.getOrderStatus();
        // 更改条件
        List<String> orderIds = updateOrderStatus.getOrderId();
        // 更改的那个字段
        String  column = updateOrderStatus.getColumn();

        // 在方法最前面加
        if (!OrderSqlProvider.ALLOWED_COLUMNS.contains(column)) {
            log.warn("非法列名被拦截: {}", column);
            return Result.error("非法的列名: " + column);
        }

        List<Order> orders;
        try {
            orders = orderMapper.orderExists(orderIds); // 假设新增此方法：SELECT * FROM orders WHERE order_id IN (...)
        } catch (Exception e) {
            log.error("查询订单信息失败，订单IDs: {}", orderIds, e);
            return Result.error("系统繁忙，请稍后重试");
        }

        if (orders.isEmpty()) {
            return Result.error("订单不存在");
        }

        log.info("查询到的订单{}", orders);
//         4. 验证订单ID是否全部存在（防止传入无效ID）

        Set<String> dbOrderIds = orders.stream().map(Order::getOrderId).collect(Collectors.toSet());
        Set<String> inputOrderIds = new HashSet<>(orderIds);
        if (!dbOrderIds.containsAll(inputOrderIds)) {
            Set<String> missing = new HashSet<>(inputOrderIds);
            missing.removeAll(dbOrderIds);
            log.warn("用户[{}]尝试操作不存在的订单: {}", wxName, missing);
            return Result.error("以下订单号不存在: " + String.join(",", missing));
        }

        List<String> failedOrders = new ArrayList<>();
        List<String> successOrders = new ArrayList<>();

        for (Order order : orders) {
            String orderId = order.getOrderId();
            Integer currentStatus = order.getOrderStatus();

            // 状态合法性校验（示例：不允许逆向变更，且不能重复设置）
            if (currentStatus == null) {
                log.warn("订单[{}]当前状态为空，无法变更", orderId);
                failedOrders.add(orderId + "(状态为空)");
                continue;
            }

            if (currentStatus.equals(targetStatus)) {
                log.debug("订单[{}]状态已是{}, 无需变更", orderId, targetStatus);
                failedOrders.add(orderId + "(状态一致,无需变更)");
                continue;
            }

            if("order_status".equals(column)){
                Integer num = Integer.parseInt(targetStatus);
                // 核心：定义合法的状态流转（根据你的业务逻辑调整）
                if (currentStatus >= num) {
                    log.warn("订单[{}]状态不允许从{}变更为{}", orderId, currentStatus, targetStatus);
                    failedOrders.add(orderId + "(状态一致，不允许变更)");
                    continue;
                }
            }

            // 6. 执行更新
            try {
                int updated = orderMapper.updateOrderStatus(orderId, targetStatus, column);
                if (updated == 1) {
                    log.info("用户[{}]成功将订单[{}]的[{}]字段从{}更新为{}", wxName, orderId,column, currentStatus, targetStatus);
                    successOrders.add(orderId);
                } else {
                    log.warn("订单[{}]状态更新失败，可能已被修改", orderId);
                    failedOrders.add(orderId + "(更新失败)");
                }
            } catch (Exception e) {
                log.error("更新订单[{}]状态时发生数据库异常", orderId, e);
                failedOrders.add(orderId + "(更新时系统异常)");
            }
        }

        // 7. 返回结果汇总
        if (failedOrders.isEmpty()) {
            return Result.success("所有订单状态更新成功");
        } else if (successOrders.isEmpty()) {
            return Result.error("所有订单更新失败" + failedOrders);
        } else {
            return Result.success("部分成功" + Map.of(
                    "successCount", successOrders.size(),
                    "failCount", failedOrders.size(),
                    "failedOrders", failedOrders,
                    "message", "共" + orderIds.size() + "个订单，成功" + successOrders.size() + "个，失败" + failedOrders.size() + "个"
            ));
        }
    }

    /**
     * 下单前判断用户的状态
     *
     * @param request
     * @return
     */
    @Override
    public Boolean UserOrderEligibilityService(HttpServletRequest request) {
        // 1. 获取 token 中的用户数据
        Map<String, Object> tokenData = getTokenData(request);
        if (tokenData == null || !tokenData.containsKey("id")) {
            log.error("用户未登录或令牌无效");
            return false;
        }

        // 2. 安全获取并验证用户 ID（Integer 类型）
        Integer idObj = (Integer) tokenData.get("id");
        if (idObj == null || !(idObj instanceof Integer)) {
            log.error("用户ID不能为空或类型错误，实际类型: {}", idObj != null ? idObj.getClass().getSimpleName() : "null");
            return false;
        }

        // 5. 查询用户信息
        Users users = userMapper.getUserById(idObj);
        if (users == null) {
            log.error("根据订单ID查询的用户不存在: {}", idObj);
            return false;
        }

        // 6. 检查用户状态
        if (users.getStatus() != UserStatus.ENABLED) {
            log.error("账号已被限制，当前状态: {}", users.getStatus());
            return false;
        }

        // 所有校验通过
        return true;
    }


    /**
     * 关闭订单
     *
     * @param orderId
     */
    @Override
    public Integer closeOrder(String orderId) {
        Integer updatedRows = orderMapper.closeOrderId(orderId);
        return updatedRows;
    }

    /**
     * 批量创建订单
     *
     * @param inputStream
     * @return
     */

    @Override
    public Result readExcelFile(InputStream inputStream, HttpServletRequest request) throws JsonProcessingException {
        // 1. 获取用户信息
        Map<String, Object> tokenData = getTokenData(request);
        String username = tokenData.get("id").toString();
        String roomname = tokenData.get("wxName").toString();

        // 2. 初始化统计和错误收集
        int successCount = 0;
        int failCount = 0;
        List<Map<String, Object>> errorDetails = new ArrayList<>();
        int totalRows = 0;
        int processedRows = 0;

        // 新增：订单映射表（订单号 -> 订单对象）
        Map<String, Order> orderMap = new HashMap<>();

        try (Workbook workbook = WorkbookFactory.create(inputStream)) {
            Sheet sheet = workbook.getSheetAt(0);
            totalRows = sheet.getLastRowNum();

            // 3. 处理每一行数据
            for (int rowIndex = 1; rowIndex <= totalRows; rowIndex++) {
                Row row = sheet.getRow(rowIndex);
                if (row == null || isEmptyRow(row)) continue;

                processedRows++;
                String currentOrderId = "未生成";
                Map<String, Object> rowData = new HashMap<>();

                try {
                    // 4. 解析基础数据
                    String platform = getCleanCellValue(row.getCell(1));
                    if (StringUtils.isEmpty(platform)) {
                        throw new Exception("平台信息不能为空");
                    }
                    platform = platform.trim();

                    String externalOrderId = getCleanCellValue(row.getCell(0));
                    externalOrderId = externalOrderId != null ? externalOrderId.trim() : null;

                    if ("抖音".equalsIgnoreCase(platform) && StringUtils.isEmpty(externalOrderId)) {
                        throw new Exception("抖音平台订单必须提供订单号");
                    }

                    // 5. 生成/使用订单号
                    String systemOrderId = StringUtils.isEmpty(externalOrderId)
                            ? OrderNumberGenerator.generateOrderNumber()
                            : externalOrderId;
                    currentOrderId = systemOrderId;

                    // 6. 解析收件人信息
                    String receiverPerson = getCleanCellValue(row.getCell(2));
                    if (StringUtils.isEmpty(receiverPerson)) {
                        throw new Exception("收件人姓名不能为空");
                    }
                    receiverPerson = receiverPerson.trim();

                    String phone = getCleanCellValue(row.getCell(3));
                    if (!isValidPhone(phone)) {
                        throw new Exception("手机号格式不正确");
                    }
                    phone = phone.trim();

                    // 7. 解析地址
                    String address = getCleanCellValue(row.getCell(4));
                    if (StringUtils.isEmpty(address)) {
                        throw new Exception("收货地址不能为空");
                    }
                    address = address.trim();
                    Map<String, Object> addressData = parseAddress(address);
                    String province = addressData.get("province").toString();
                    String city = addressData.get("city").toString();
                    String county = addressData.get("county").toString();
                    String street = addressData.get("street").toString();

                    // 8. 处理商品信息
                    String productCode = getCleanCellValue(row.getCell(5));
                    if (StringUtils.isEmpty(productCode)) {
                        throw new Exception("商品编码不能为空");
                    }
                    productCode = productCode.trim();

                    Products product = orderMapper.getProductByCode(productCode);
                    if (product == null) {
                        throw new Exception("未找到商品: " + productCode);
                    }

                    // 9. 处理商品数量
                    String quantityStr = getCleanCellValue(row.getCell(6));
                    int quantity;
                    try {
                        quantity = Integer.parseInt(quantityStr.trim());
                        if (quantity <= 0) throw new Exception("商品数量必须大于0");
                    } catch (Exception e) {
                        throw new Exception("商品数量必须是整数");
                    }

                    // 10. 买家留言
                    String customerNote = getCleanCellValue(row.getCell(7));
                    customerNote = customerNote != null ? customerNote.trim() : "";

                    // 11. 检查订单是否存在
                    Order order = orderMap.get(systemOrderId);
                    if (order == null) {
                        // 创建新订单
                        order = new Order();
                        order.setRoomname(roomname);
                        order.setUsername(username);
                        order.setCreatedAt(LocalDateTime.now());
                        order.setUpdatedAt(LocalDateTime.now());
                        order.setOrderStatus(0);
                        order.setPlatform(platform);
                        order.setOrderId(systemOrderId);
                        order.setReceiverPerson(receiverPerson);
                        order.setReceiverPhone(phone);
                        order.setReceiverProvince(province);
                        order.setReceiverCity(city);
                        order.setReceiverCounty(county);
                        order.setReceiverStreet(street);
                        order.setCustomerNote(customerNote);

                        // 插入新订单
                        try {
                            orderMapper.insertOrder(order);
                            orderMap.put(systemOrderId, order);
                        } catch (DataAccessException e) {
                            throw new Exception(extractUserFriendlyError(e));
                        }
                    } else {
                        // 校验订单信息一致性
                        if (!receiverPerson.equals(order.getReceiverPerson())) {
                            throw new Exception("收件人姓名与同一订单的其他行不一致");
                        }
                        if (!phone.equals(order.getReceiverPhone())) {
                            throw new Exception("收件人电话与同一订单的其他行不一致");
                        }
                        if (!province.equals(order.getReceiverProvince()) ||
                                !city.equals(order.getReceiverCity()) ||
                                !county.equals(order.getReceiverCounty()) ||
                                !street.equals(order.getReceiverStreet())) {
                            throw new Exception("收货地址与同一订单的其他行不一致");
                        }
                    }

                    // 12. 创建订单项
                    OrderItems item = new OrderItems();
                    item.setOrderId(systemOrderId);
                    item.setProductCode(productCode);
                    item.setProductName(product.getName());
                    item.setIsCombo(product.getIsCombination());
                    item.setSkuId(product.getErpSkuid());
                    item.setQuantity(String.valueOf(quantity));

                    // 13. 插入订单项
                    try {
                        orderMapper.insertOrderItems(item);
                        successCount++;
                    } catch (DataAccessException e) {
                        throw new Exception(extractUserFriendlyError(e));
                    }

                } catch (Exception e) {
                    failCount++;
                    Map<String, Object> errorInfo = new HashMap<>();
                    errorInfo.put("row", rowIndex + 1);
                    errorInfo.put("orderId", currentOrderId);
                    errorInfo.put("message", e.getMessage());
                    errorDetails.add(errorInfo);
                }
            }

            // 14. 构建结果数据
            Map<String, Object> resultData = new LinkedHashMap<>();
            resultData.put("totalRows", totalRows);
            resultData.put("processedRows", processedRows);
            resultData.put("successCount", successCount);
            resultData.put("failCount", failCount);
            resultData.put("uniqueOrders", orderMap.size()); // 新增：唯一订单数统计

            if (!errorDetails.isEmpty()) {
                resultData.put("errorDetails", errorDetails);
            }

            // 15. 生成汇总信息
            resultData.put("summary", getSummary(successCount, failCount));

            // 16. 返回Result对象
            return Result.success(resultData);

        } catch (IOException e) {
            return Result.error("Excel文件解析失败");
        } catch (Exception e) {
            return Result.error("订单导入失败: " + e.getMessage());
        }
    }


    @Value("${ERP.URL}")
    private String url;

    // 地址解析（增强错误处理）
    private Map<String, Object> parseAddress(String address) throws Exception {
        Map<String, Object> postData = new HashMap<>();
        postData.put("address", address);


        try {
//            String response = httpUtil.post("http://192.168.1.35:5000/api/address", postData);
            String response = httpUtil.post("http://" + url + "/erp/address", postData);
            JsonNode root = jsonMapper.readTree(response);

            if (!"200".equals(root.path("code").asText())) {
                String errorMsg = root.path("msg").asText("地址解析失败");
                throw new Exception(errorMsg);
            }

            JsonNode data = root.path("data");
            Map<String, Object> result = new HashMap<>();
            result.put("province", data.path("province").asText(""));
            result.put("city", data.path("city").asText(""));
            result.put("county", data.path("county").asText(""));
            result.put("street", data.path("street").asText(""));

            return result;
        } catch (Exception e) {
            throw new Exception("地址解析服务不可用");
        }
    }

    // 提取用户友好的错误信息
    private String extractUserFriendlyError(DataAccessException e) {
        String errorMsg = e.getMessage();

        // 简化数据库错误信息
        if (errorMsg.contains("cannot be null")) {
            // 提取字段名
            int start = errorMsg.indexOf("Column '");
            if (start != -1) {
                int end = errorMsg.indexOf("'", start + 8);
                if (end != -1) {
                    String column = errorMsg.substring(start + 8, end);
                    return "字段不能为空: " + translateColumnName(column);
                }
            }
            return "必填字段不能为空";
        }

        if (errorMsg.contains("Duplicate entry")) {
            return "订单号已存在";
        }

        return "数据库保存失败";
    }

    // 字段名翻译
    private String translateColumnName(String column) {
        switch (column) {
            case "platform":
                return "平台";
            case "receiver_person":
                return "收件人姓名";
            case "receiver_phone":
                return "收件人电话";
            case "receiver_street":
                return "详细地址";
            default:
                return column;
        }
    }

    // 辅助方法：生成汇总信息
    private String getSummary(int successCount, int failCount) {
        if (failCount == 0) {
            return "全部导入成功，共 " + successCount + " 条记录";
        } else if (successCount == 0) {
            return "全部导入失败，共 " + failCount + " 条记录";
        } else {
            return "部分导入成功：成功 " + successCount + " 条，失败 " + failCount + " 条";
        }
    }

    // 辅助方法：获取清理后的单元格值
    private String getCleanCellValue(Cell cell) {
        if (cell == null) return "";

        DataFormatter formatter = new DataFormatter();
        return formatter.formatCellValue(cell).trim();
    }

    // 辅助方法：验证手机号
    private boolean isValidPhone(String phone) {
        if (StringUtils.isEmpty(phone)) return false;
        return phone.matches("^1[3-9]\\d{9}(-\\d{1,6})?$");
    }

    // 辅助方法：检查空行
    private boolean isEmptyRow(Row row) {
        if (row == null) return true;

        for (int i = 0; i < row.getLastCellNum(); i++) {
            Cell cell = row.getCell(i);
            if (cell != null) {
                String value = getCleanCellValue(cell);
                if (!value.isEmpty()) {
                    return false;
                }
            }
        }
        return true;
    }

}
